/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package control;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import vista.PantallaPartida;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import modelo.Estadistica;
import modelo.Jugador;
import modelo.Partida;
import modelo.Pregunta;
import modelo.Respuesta;
import modelo.Solicitud;
import modelo.Tablero;
import modelo.Turno;
import persistencia.PersiEstadistica;
import persistencia.PersiJugador;
import persistencia.PersiPartida;
import persistencia.PersiPregunta;
import persistencia.PersiSolicitud;
import persistencia.PersiTurno;
import vista.PantallaInicio;
import vista.PanelEstadistica;
import vista.PantallaRegistro;

/**
 *
 * @author alumneDAM
 */
public class Control implements ActionListener, MouseListener, ListSelectionListener {

    private PantallaPartida pantallaPartida;
    private PantallaRegistro registro;
    private PantallaInicio inicio;

    private Estadistica estadistica;
    private Jugador jugador;
    private Partida partida;
    private Pregunta pregunta;
    private Respuesta respuesta;
    private Tablero tablero;
    private Turno turno;
    private Solicitud solicitud;

    private PersiEstadistica persiEstadistica;
    private PersiJugador persiJugador;
    private PersiPregunta persiPregunta;
    private PersiTurno persiTurno;
    private PersiPartida persiPartida;
    private PersiSolicitud persiSolicitud;

    private JButton boton;
    private Thread hiloTiempo;
    private int posicionActual;
    private int nuevaPosicion;

    public Control() {
        //Logica
        tablero = new Tablero();

        //Persistencia
        persiEstadistica = new PersiEstadistica();
        persiJugador = new PersiJugador();
        persiPregunta = new PersiPregunta();
        persiTurno = new PersiTurno();
        persiPartida = new PersiPartida();
        persiSolicitud = new PersiSolicitud();

    }

    public PantallaPartida getPantallaPartida() {
        if (pantallaPartida == null) {
            pantallaPartida = new PantallaPartida(this);
        }
        return pantallaPartida;
    }

    public PantallaInicio getPantallaInicio() {
        if (inicio == null) {
            inicio = new PantallaInicio(this);
        }
        return inicio;
    }

    public PantallaRegistro getPantallaRegistro() {
        if (registro == null) {
            registro = new PantallaRegistro(this);
        }
        return registro;
    }

    public Estadistica getEstadistica() {
        return estadistica;
    }

    public Jugador getJugador() {
        return jugador;
    }

    public Partida getPartida() {
        return partida;
    }

    public Pregunta getPregunta() {
        return pregunta;
    }

    public Respuesta getRespuesta() {
        return respuesta;
    }

    public Tablero getTablero() {
        return tablero;
    }

    public Turno getTurno() {
        return turno;
    }

    public Solicitud getSolicitud() {
        return solicitud;
    }

    public void setPregunta(Pregunta pregunta) {
        this.pregunta = pregunta;
    }

    public void setRespuesta(Respuesta respuesta) {
        this.respuesta = respuesta;
    }

    public PersiEstadistica getPersiEstadistica() {
        return persiEstadistica;
    }

    public PersiJugador getPersiJugador() {
        return persiJugador;
    }

    public PersiPregunta getPersiPregunta() {
        return persiPregunta;
    }

    public PersiTurno getPersiTurno() {
        return persiTurno;
    }

    public PersiPartida getPersiPartida() {
        return persiPartida;
    }

    public JButton getBoton() {
        return boton;
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        String accion = e.getActionCommand();

        if (accion.equals("respuesta1") || accion.equals("respuesta2") || accion.equals("respuesta3") || accion.equals("respuesta4")) {
            boton = (JButton) e.getSource();
        }

        Runnable r = new Runnable() {

            @Override
            public void run() {
                try {
                    hiloTiempo.stop();
                    pantallaPartida.getPanelPreguntas().deshabilitarBotones();
                    boton.setBackground(Color.RED);
                    String resp = pantallaPartida.getPanelPreguntas().mostrarRespuestaCorrecta();
                    Thread.sleep(2000);
                    pantallaPartida.getPanelPreguntas().comprobarRespuesta(boton, resp, nuevaPosicion);
                    pantallaPartida.getPanelPreguntas().setVisible(false);
                    pantallaPartida.getPanelPreguntas().inicializarPanelPreguntas();
                    pantallaPartida.getPanelTablero().visibilidadBotonesCategorias(false);
                    pantallaPartida.getPanelTablero().cargarTablero();
                } catch (InterruptedException ex) {
                    System.out.println("Error al mostrar respuesta correcta");
                }
            }
        };

        Runnable runTiempo = new Runnable() {

            @Override
            public void run() {
                boolean tiempoAcabado = pantallaPartida.getPanelPreguntas().tiempoPregunta();

                if (tiempoAcabado) {
                    JOptionPane.showMessageDialog(pantallaPartida, "El tiempo se ha agotado, has perdido el turno", "¡TIEMPO AGOTADO!", 1);
                    pantallaPartida.cambiarPanel("PanelTablero");
                    if (partida.getTurno().getJugadorActivo().equals(partida.getId_jugador1())) {
                        partida.nuevoTurno(partida.getId_jugador2());
                    } else {
                        partida.nuevoTurno(partida.getId_jugador1());
                    }
                    persiTurno.modificaTurno(partida.getTurno());
                }
            }
        };

        switch (accion) {
            case "Categoria1":
                nuevaPosicion = pantallaPartida.getPanelTablero().getPosicionCategoria1();
                pantallaPartida.getPanelPreguntas().colocarPreguntaYRespuestas(nuevaPosicion);
                pantallaPartida.cambiarPanel("PanelPreguntas");
                hiloTiempo = new Thread(runTiempo);
                hiloTiempo.start();
                break;

            case "Categoria2":
                nuevaPosicion = pantallaPartida.getPanelTablero().getPosicionCategoria2();
                pantallaPartida.getPanelPreguntas().colocarPreguntaYRespuestas(nuevaPosicion);
                pantallaPartida.cambiarPanel("PanelPreguntas");
                hiloTiempo = new Thread(runTiempo);
                hiloTiempo.start();
                break;

            case "respuesta1":
                Thread hilo = new Thread(r);
                hilo.start();
                break;

            case "respuesta2":
                Thread hilo2 = new Thread(r);
                hilo2.start();
                break;

            case "respuesta3":
                Thread hilo3 = new Thread(r);
                hilo3.start();
                break;

            case "respuesta4":
                Thread hilo4 = new Thread(r);
                hilo4.start();
                break;

            case "Entrar":
                //Llamar al método validarUsuario
                jugador = inicio.validarUsuario();
                if (jugador != null) {
                    this.getPantallaInicio().setVisible(false);
                    this.getPantallaPartida().getPanelTablero();

                    //Cargamos partidas del lateral izquierdo
                    pantallaPartida.getPanelPartidasIniciadas().
                            rellenarPartidas(persiPartida.cargarPartidas(jugador.getNickname()));
                    pantallaPartida.getPanelPartidasIniciadas().
                            rellenarSolicitudes(persiSolicitud.cargarSolicitudes(jugador.getNickname()));
                    partida = (Partida) pantallaPartida.getPanelPartidasIniciadas().recuperarPartida1();
                    if (partida.getTurno().getJugadorActivo().equals(jugador.getNickname())
                            && partida.getTurno().getJugadorActivo().equals(partida.getId_jugador1())) {
                        posicionActual = partida.getPosicionJ1();
                    } else {
                        posicionActual = partida.getPosicionJ2();
                    }
                    pantallaPartida.getPanelTablero().cargarTablero();

                }
                break;

            case "Registrarse":
                getPantallaRegistro();
                registro.setVisible(true);
                this.getPantallaInicio().setVisible(false);
                break;

            case "Registrar":
                if (registro.compruebaRegistro()) {
                    //guardar los datos del jugador 
                    jugador = registro.nuevoJugador();
                    persiJugador.guardarJugador(jugador);
                    this.getPantallaPartida().setVisible(true);
                    registro.setVisible(false);
                }
                break;
                
            //Se abre la vista de nueva partida
            case "nuevaPartida":
                pantallaPartida.cambiarPanel("NuevaPartida");
                break;
            //Cuando se pulsa al boton despues de añadir un jugador con el 
            //que se quiere Jugar
            case "BuscarJugador":
                //Se recoje el nick del jugador
                String jugadorSolicitat = pantallaPartida.getNuevaPartida().getTxt_buscar().getText();

                //Se comprueba si existe
                if ((persiJugador.leerJugador(jugadorSolicitat) == null) 
                        || (jugador.getNickname().equals(jugadorSolicitat))) {
                    pantallaPartida.getNuevaPartida().muestraError();
                } else {
                    //Se crea la solicitud de Juego.
                    solicitud = new Solicitud(jugador.getNickname(), jugadorSolicitat);
                }
                pantallaPartida.cambiarPanel("PanelTablero");
                break;

            case "verEstadisticas":
                pantallaPartida.cambiarPanel("Estadistica");

                PanelEstadistica panelEstadistica = pantallaPartida.getPanelEstadisica();

                int[] porcentajes = persiEstadistica.estadisticaRespuestasJugador(jugador.getNickname());

                panelEstadistica.rellenarProgressBars(porcentajes);

                int[] datos = {persiEstadistica.partidasGanadas(jugador.getNickname()),
                    persiEstadistica.partidasTerminadas(jugador.getNickname())};

                panelEstadistica.rellenarDatosPartidas(datos);

                break;

            case "IniciarNuevaPartida":
                pantallaPartida.cambiarPanel("NuevaPartida");
                break;
        }
        pantallaPartida.getPanelPartidasIniciadas().
                rellenarPartidas(persiPartida.cargarPartidas(jugador.getNickname()));
    }

    @Override
    public void mouseClicked(MouseEvent me) {
        
        if ("JMenu".equals(me.getSource().getClass().getSimpleName())) {
            System.exit(0);
        } else if ("JList".equals(me.getSource().getClass().getSimpleName())) {
            pantallaPartida.getPanelTablero().setVisible(true);
            partida = (Partida) this.getPantallaPartida().getPanelPartidasIniciadas().recuperarPartida();
            partida.cargarPartida(partida.getId_partida());
            if (partida.getTurno().getJugadorActivo().equals(jugador.getNickname()) && partida.getId_jugador1().equals(jugador.getNickname())) {
                posicionActual = partida.getPosicionJ1();
            } else if (partida.getTurno().getJugadorActivo().equals(jugador.getNickname()) && partida.getId_jugador2().equals(jugador.getNickname())) {
                posicionActual = partida.getPosicionJ2();
            }
            pantallaPartida.getPanelTablero().cargarTablero();
            pantallaPartida.getPanelTablero().repaint();
        } else if ("JLabel".equals(me.getSource().getClass().getSimpleName())) {
            partida.getTurno().setNumeroSacado(partida.getTurno().lanzarDado());
            persiTurno.guardarDadoTirado(partida.getId_partida(), partida.getTurno().getIdTurno(), 1, partida.getTurno().getNumeroSacado());
            if (partida.getTurno().getJugadorActivo().equals(jugador.getNickname()) && partida.getTurno().getJugadorActivo().equals(partida.getId_jugador1())) {
                posicionActual = partida.getPosicionJ1();
            } else {
                posicionActual = partida.getPosicionJ2();
            }
            pantallaPartida.getPanelTablero().calculoCategorias(posicionActual);
            pantallaPartida.getPanelTablero().dadoFijo();
        }
        pantallaPartida.getPanelPartidasIniciadas().
                rellenarPartidas(persiPartida.cargarPartidas(jugador.getNickname()));
        pantallaPartida.getPanelPartidasIniciadas().rellenarSolicitudes(persiSolicitud.cargarSolicitudes(jugador.getNickname()));
    }

    @Override
    public void mousePressed(MouseEvent me) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void mouseReleased(MouseEvent me) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void mouseEntered(MouseEvent me) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void mouseExited(MouseEvent me) {
        // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void valueChanged(ListSelectionEvent lse) {
        Solicitud solicitud = (Solicitud) pantallaPartida.getPanelPartidasIniciadas().recuperaSolicitud();
        int opcion = pantallaPartida.getPanelPartidasIniciadas().muestraAceptarSolicitud();
        if (opcion == 1) {
            solicitud.responderSolicitud(solicitud.getId_solicitud(), false);
        } else {
            //Crear partida nueva y borrar la solicitud
            new Partida(solicitud.getId_jugador1(), solicitud.getId_jugador2(), 1);
            solicitud.responderSolicitud(solicitud.getId_solicitud(), true);
        }
    }

}
